package hu.fic.weddingstorefinder.db;

import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class Table {

	private static final String LOG_TAG = "Table";

	public static final int STATE_CLOSED = -2;
	public static final int STATE_LOADED = -1;
	public static final int STATE_EOF = -3;

	protected SQLiteDatabase db;
	protected String sqlOrderBy = null;

	protected Cursor cursor;
	protected Activity activity;
	protected int rowpos = STATE_CLOSED;

	public Table(SQLiteDatabase db, Activity activity) {
		this.db = db;
		this.activity = activity;
	}

	public String stringToSql(String str) {
		return "'" + str + "'";
	}

	/**
	 * @param sql
	 */
	public void load(String sql) throws Exception {
		rowpos = STATE_LOADED;
		this.cursor = this.db.rawQuery(sql, null);
		activity.startManagingCursor(cursor);
		cursor.moveToFirst();
	}

	public void execStatement(String sql) {
		this.db.execSQL(sql);
	}

	public boolean nextRow() {
		try {
			if (this.cursor == null) {
				throw new IllegalArgumentException("ERROR: using nextRow() before load()." + this.getClass().getName().toString());
			}
			// If there isn`t any row//
			if ((this.cursor.getCount() == 0)) {
				return false;
			} else if (rowpos == STATE_LOADED) {
				rowpos = 0;
				cursor.moveToFirst();
				return true;
			} else if (rowpos > STATE_LOADED) {
				rowpos++;
				if (!this.cursor.moveToNext()) {
					rowpos = STATE_EOF;
					return false;
				}
				return true;
			} else if (rowpos == STATE_EOF) {
				return false;
			}
			return false;
		} catch (IllegalArgumentException ex) {
			Log.e(LOG_TAG, ex.getMessage(), ex);
			return false;
		} catch (Exception ex) {
			Log.e(LOG_TAG, ex.getMessage(), ex);
			return false;
		}
	}

	public long getTimestamp(int colIndex) {
		try {
			long tcucc = cursor.getLong(colIndex);

			if (tcucc == 0) {
				return 0;
			} else
			/** @todo: It is just workaround - gettimestamp(colname, calendar). */
			{
				return tcucc;
			}
		} catch (Exception ex) {
			return -1;
		}
	}

	public long getTimestamp(String colName) {
		try {
			//long tcucc = this.getTimestamp(getIntForColumnName(colName));
			long tcucc = this.getTimestamp(cursor.getColumnIndex(colName));

			if (tcucc == 0) {
				return 0;
			} else
			/** @todo: It is just workaround - gettimestamp(colname, calendar). */
			{
				return tcucc;
			}
		} catch (Exception ex) {
			return -1;
		}
	}

	public String getString(int colId) {
		try {
			return cursor.getString(colId);
		} catch (Exception ex) {
			Log.e(LOG_TAG, ex.getMessage(), ex);
			return null;
		}
	}

	public String getString(String colName) {
		try {
			//return this.getString(getIntForColumnName(colName));
			return this.getString(cursor.getColumnIndex(colName));
		} catch (Exception ex) {
			Log.e(LOG_TAG, ex.getMessage(), ex);
			return null;
		}
	}

	public double getDouble(int colId) {
		try {
			return cursor.getDouble(colId);
		} catch (Exception ex) {
			Log.e(LOG_TAG, ex.getMessage(), ex);
			return 0.0;
		}
	}

	public double getDouble(String colName) {
		try {
			//return this.getDouble(getIntForColumnName(colName));
			return this.getDouble(cursor.getColumnIndex(colName));
		} catch (Exception ex) {
			Log.e(LOG_TAG, ex.getMessage(), ex);
			return 0.0;
		}
	}

	public int getInt(int colId) {
		try {
			return cursor.getInt(colId);
		} catch (Exception ex) {
			Log.e(LOG_TAG, ex.getMessage(), ex);
			return 0;
		}
	}

	public int getInt(String colName) {
		try {
			//return this.getInt(getIntForColumnName(colName));
			return this.getInt(cursor.getColumnIndexOrThrow(colName));
		} catch (Exception ex) {
			Log.e(LOG_TAG, ex.getMessage(), ex);
			return 0;
		}
	}

	public int rowCount() {
		return cursor.getCount();
	}

	public void first() {
		try {
			cursor.moveToFirst();
			this.rowpos = STATE_LOADED;
		} catch (Exception ex) {
		}
	}

	public void clear() {
		rowpos = STATE_CLOSED;
		if (cursor != null) {
			activity.stopManagingCursor(cursor);
			cursor.close();
		}
	}
	
	public int getIntForColumnName(String columnName) {
		String columnNames[] = cursor.getColumnNames();
		for (int i = 0;i<columnNames.length;i++) {
			if (columnName.equals(columnNames[i])) {
				return i;
			} else {
				String replacedColumn = columnNames[i].replace(".", ":");
				String splitted[] = replacedColumn.split(":");
				if (splitted.length > 0 && splitted[splitted.length-1].equals(columnName)) {
					return i;
				}
			}
		}
		return 0;
	}

	public class SQLStatement {
		private String table = "";
		private String out = "";
		private String where = "";
		private String tail = "";
		private String set = "";
		boolean emptyset = true;
		boolean emptywhere = true;
		boolean emptytable = true;
		boolean emptyout = true;

		public void addTable(String name) {
			addTable(name, false);
		}

		public void addTable(String name, boolean out) {
			if (name == null)
				return;

			if (!emptytable) {
				table += ", ";
			}
			if (out) {
				addOut(name);
			}

			table += name;
			emptytable = false;
		}

		public void addOut(String name) {
			if (name == null)
				return;

			if (!emptyout) {
				out += ", ";
			}

			out += name + ".*";
			emptyout = false;
		}

		public void addOutField(String tab, String name) {
			if (name == null)
				return;

			if (!emptyout) {
				out += ", ";
			}

			out += tab + "." + name;
			emptyout = false;
		}

		public void addOutField(String tab, String name, int sqlType) {
			if (name == null)
				return;

			if (!emptyout) {
				out += ", ";
			}

			out += tab + "." + name;
			emptyout = false;
		}

		public void addTail(String t) {
			if (!((sqlOrderBy != null) && (t.indexOf("ORDER BY") != -1))) {
				tail += t;
			}
		}

		public void addTail() {
		}

		public void addDoubleFilter(String name, Double f) {
			if (f != null) {
				if (!emptywhere)
					where += " AND ";
				where += name + "=" + f;
				emptywhere = false;
			}
		}

		public void addIntFilter(String name, Integer f) {
			if (f != null) {
				if (!emptywhere)
					where += " AND ";
				where += name + "=" + f;
				emptywhere = false;
			}
		}

		public void addShortFilter(String name, Short f) {
			if (f != null) {
				if (!emptywhere)
					where += " AND ";
				where += name + "=" + f;
				emptywhere = false;
			}
		}

		public void addFilter(String c) {
			if (c != null) {
				if (!emptywhere)
					where += " AND ";
				where += c;
				emptywhere = false;
			}
		}

		public void addNullFilter(String c) {
			if (c != null) {
				if (!emptywhere)
					where += " AND ";
				where += c + " IS NULL";
				emptywhere = false;
			}
		}

		public void addStrFilter(String name, String f) {
			if (f != null) {
				if (!emptywhere)
					where += " AND ";
				where += name + "=" + stringToSql(f);
				emptywhere = false;
			}
		}

		public void addInputStreamFilter(String name, java.io.InputStream f) {
			if (f != null) {
				if (!emptywhere)
					where += " AND ";
				where += name + "=" + f;
				emptywhere = false;
			}
		}

		public void addLikeFilter(String name, String f) {
			if (f != null) {
				if (!emptywhere)
					where += " AND ";
				where += name + " LIKE " + stringToSql(f);
				emptywhere = false;
			}
		}

		public void addLongFilter(String name, Long f) { // throws InetBuyerException{
			if (f != null) {
				if (!emptywhere)
					where += " AND ";
				where += name + "=" + f;
				emptywhere = false;
			}
		}

		public void addDoubleSet(String name, Double f) {
			if (f != null) {
				if (!emptyset)
					set += ", ";
				set += name + "=" + f;
				emptyset = false;
			}
		}

		public void addIntSet(String name, Integer f) {
			if (f != null) {
				if (!emptyset)
					set += ", ";
				set += name + "=" + f;
				emptyset = false;
			}
		}

		public void addShortSet(String name, Short f) {
			if (f != null) {
				if (!emptyset)
					set += ", ";
				set += name + "=" + f;
				emptyset = false;
			}
		}

		public void addLongSet(String name, Long f) {
			if (f != null) {
				if (!emptyset)
					set += ", ";
				set += name + "=" + f;
				emptyset = false;
			}
		}

		public void addStringSet(String name, String f) {
			if (f != null) {
				if (!emptyset)
					set += ", ";
				set += name + "=" + stringToSql(f);
				emptyset = false;
			}
		}

		public String getSql() {
			if (emptywhere)
				return "SELECT * " + out + " FROM " + table + tail;
			else
				return "SELECT * " + out + " FROM " + table + " WHERE " + where + tail;
		}

		public String getDeleteSql() {
			if (emptywhere) {
				Log.e(LOG_TAG, "Use set method to delete, or use deleteAll");
				return "";
			} else {
				return "DELETE FROM " + table + " WHERE " + where;
			}
		}

		public String getDeleteAllSql() {
			return "DELETE FROM " + table;
		}

		public String getUpdateSql() {
			if (emptyset) {
				Log.e(LOG_TAG, "Use set method to update!");
				return "";
			} else {
				if (!emptywhere) {
					return "UPDATE " + table + " SET " + set + " WHERE " + where;
				} else {
					return "UPDATE " + table + " SET " + set;
				}
			}
		}

	}


}
